package org.bankabeule.ui.views;

import org.bankabeule.Model;
import org.bankabeule.Operation;
import org.bankabeule.Tag;
import org.bankabeule.ui.Activator;
import org.bankabeule.ui.actions.AddTagAction;
import org.bankabeule.ui.actions.EditTagAction;
import org.bankabeule.ui.actions.RemoveAction;
import org.bankabeule.util.Providers;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IWorkbenchActionConstants;

public class TagsView extends AbstractViewPart {

	/**
	 * ID
	 */
	public static final String ID = "org.bankabeule.ui.views.TagsView";

	/**
	 * Tree viewer
	 */
	private TreeViewer viewer;

	/**
	 * The constructor.
	 */
	public TagsView() {
		super();
	}

	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {	
		// create viewer
		viewer = new TreeViewer(parent);
		viewer.setContentProvider(Providers.getContentProvider());
		viewer.setLabelProvider(Providers.getLabelProvider());
		viewer.addFilter(new ViewerFilter() {
			@Override
			public boolean select(Viewer viewer, Object parentElement,
					Object element) {
				return element instanceof Tag;
			}
		});
		
		// add actions
		IToolBarManager toolbar = getViewSite().getActionBars().getToolBarManager();
		toolbar.add(new AddTagAction(viewer));		
        toolbar.add(new Action("Collapse All", Activator.getImageDescriptor("CollapseAll.gif")) {
			@Override
			public void run() {
				viewer.collapseAll();
			}
		});
		toolbar.add(new Action("Expand All", Activator.getImageDescriptor("ExpandAll.gif")) {
			@Override
			public void run() {
				viewer.expandAll();
			}
		});
		
		// add contextual menu
		MenuManager contextMenu = new MenuManager("#PopUp"); //$NON-NLS-1$
        contextMenu.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                manager.removeAll();
                manager.add(new AddTagAction(viewer));
                manager.add(new EditTagAction(viewer));
                manager.add(new RemoveAction(viewer));
                manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));

            }

        });
        Menu menu = contextMenu.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        
        // add drag support
        viewer.addDragSupport(DND.DROP_MOVE, 
        		new Transfer[] {LocalSelectionTransfer.getTransfer()}, new DragSourceAdapter() {
        	@Override
            public void dragStart(DragSourceEvent event) {
                LocalSelectionTransfer.getTransfer().setSelection(viewer.getSelection());
                event.doit = true;
            }
        	@Override
			public void dragSetData(DragSourceEvent event) {
				if (LocalSelectionTransfer.getTransfer().isSupportedType(event.dataType)) {
					event.data = viewer.getSelection();
				}
			}
        	@Override
			public void dragFinished(DragSourceEvent event) {
        		LocalSelectionTransfer.getTransfer().setSelection(null);
			}
        });
        viewer.addDropSupport(DND.DROP_MOVE, new Transfer[] {LocalSelectionTransfer.getTransfer()}, 
        		new DropTargetAdapter() {
        	@Override
        	public void drop(DropTargetEvent event) {
        		if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)) {
        			StructuredSelection selection = (StructuredSelection) event.data;
        			Tag tag = (Tag) ((TreeItem) event.item).getData();
        			for (Object object : selection.toList()) {
        				((Operation) object).getTags().add(tag);
        			}
        		}
        	}
        });
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getTree().setFocus();
	}

	public void modelLoaded(Model model) {
		super.modelLoaded(model);
		viewer.setInput(model);
		viewer.expandAll();
	}

	public void modelUnloaded(Model model) {
		super.modelUnloaded(model);
		viewer.setInput(null);
	}

}